﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;
using System.Windows.Data;
using SLControlLibrary.Resources.Controls.Calendar.OutlookCalendar.BusinessObjects;
using SLControlLibrary.Resources.Controls.Calendar.OutlookCalendar.DataAccess;
using SLControlLibrary.Resources.Controls.Calendar.OutlookCalendar.ViewModel;
using SLControlLibrary.Resources.Controls.Calendar.DatePicker;
using SLControlLibrary.Resources.Controls.Calendar.Events;

namespace SLControlLibrary.Resources.Controls.Calendar.OutlookCalendar
{
    public class ucEditAppointment : Control
    {
        #region Dependency Variables
        private static readonly DependencyProperty StartDateProperty = DependencyProperty.Register("StartDate", typeof(DateTime), typeof(ucEditAppointment), new PropertyMetadata(DateTime.Now, new PropertyChangedCallback(StartDate_Changed)));
        private static readonly DependencyProperty EndDateProperty = DependencyProperty.Register("EndDate", typeof(DateTime), typeof(ucEditAppointment), new PropertyMetadata(DateTime.Now, new PropertyChangedCallback(EndDate_Changed)));
        private static readonly DependencyProperty StartTimeProperty = DependencyProperty.Register("StartTime", typeof(TimeSpan), typeof(ucEditAppointment), new PropertyMetadata(DateTime.Now.TimeOfDay, new PropertyChangedCallback(StartTime_Changed)));
        private static readonly DependencyProperty EndTimeProperty = DependencyProperty.Register("EndTime", typeof(TimeSpan), typeof(ucEditAppointment), new PropertyMetadata(DateTime.Now.TimeOfDay, new PropertyChangedCallback(EndTime_Changed)));
        private static readonly DependencyProperty DescProperty = DependencyProperty.Register("Desc", typeof(string), typeof(ucEditAppointment), new PropertyMetadata("", new PropertyChangedCallback(Desc_Changed)));
        private static readonly DependencyProperty IsNewAppointmentProperty = DependencyProperty.Register("IsNewAppointment", typeof(Visibility), typeof(ucEditAppointment), new PropertyMetadata(Visibility.Collapsed, new PropertyChangedCallback(IsNewAppointment_Changed)));
        private static readonly DependencyProperty CurrentAppointmentProperty = DependencyProperty.Register("CurrentAppointment", typeof(Appointment), typeof(ucEditAppointment), new PropertyMetadata(null, new PropertyChangedCallback(CurrentAppointment_Changed)));
        #endregion

        #region Dependency Properties
        public DateTime StartDate
        {
            get { return (DateTime)this.GetValue(StartDateProperty); }
            set { this.SetValue(StartDateProperty, value); }
        }
        public DateTime EndDate
        {
            get { return (DateTime)this.GetValue(EndDateProperty); }
            set { this.SetValue(EndDateProperty, value); }
        }
        public TimeSpan StartTime
        {
            get { return (TimeSpan)this.GetValue(StartTimeProperty); }
            set { this.SetValue(StartTimeProperty, value); }
        }
        public TimeSpan EndTime
        {
            get { return (TimeSpan)this.GetValue(EndTimeProperty); }
            set { this.SetValue(EndTimeProperty, value); }
        }
        public string Desc
        {
            get { return this.GetValue(DescProperty).ToString(); }
            set { this.SetValue(DescProperty, value); }
        }
        public Visibility IsNewAppointment
        {
            get { return (Visibility)this.GetValue(IsNewAppointmentProperty); }
            set { this.SetValue(IsNewAppointmentProperty, value); }
        }
        public Appointment CurrentAppointment
        {
            get { return (Appointment)this.GetValue(CurrentAppointmentProperty); }
            set { this.SetValue(CurrentAppointmentProperty, value); }
        }
        #endregion

        #region Dependency Events
        #region StartDate_Changed
        private static void StartDate_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ucEditAppointment).OnStartDate_Changed(e);
        }
        #endregion

        #region EndDate_Changed
        private static void EndDate_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ucEditAppointment).OnEndDate_Changed(e);
        }
        #endregion

        #region StartTime_Changed
        private static void StartTime_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ucEditAppointment).OnStartTime_Changed(e);
        }
        #endregion

        #region EndTime_Changed
        private static void EndTime_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ucEditAppointment).OnEndTime_Changed(e);
        }
        #endregion

        #region Desc_Changed
        private static void Desc_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ucEditAppointment).OnDesc_Changed(e);
        }
        #endregion

        #region IsNewAppointment_Changed
        private static void IsNewAppointment_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ucEditAppointment).OnIsNewAppointment_Changed(e);
        }
        #endregion

        #region CurrentAppointment_Changed
        private static void CurrentAppointment_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            (sender as ucEditAppointment).OnCurrentAppointment_Changed(e);
        }
        #endregion
        #endregion

        #region Variables
        private Button btnSubmit = null;
        private Ellipse btnClose = null;
        private TextBlock lblClose = null;
        private ComboBox cboImportance = null;
        private TextBox txtDesc = null;
        private TextBox txtStartTime = null;
        private TextBox txtEndTime = null;
        private ucDatePicker dpStartDate = null;
        private ucDatePicker dpEndDate = null;
        private bool HasLoaded = false;
        #endregion

        #region Event Variables
        public event EventHandler Appointment_Submited;
        public event EventHandler Appointment_Closed;
        #endregion

        #region Constructor
        public ucEditAppointment()
        {
            DefaultStyleKey = typeof(ucEditAppointment);
        }
        #endregion

        #region Methods
        #region OnApplyTemplate
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            btnSubmit = (Button)base.GetTemplateChild("btnSubmit");

            if (btnSubmit == null) return;

            btnSubmit.Click += new RoutedEventHandler(btnSubmit_Click);

            btnClose = (Ellipse)base.GetTemplateChild("btnClose");

            if (btnClose == null) return;

            btnClose.MouseLeftButtonUp += new MouseButtonEventHandler(btnClose_MouseLeftButtonUp);

            lblClose = (TextBlock)base.GetTemplateChild("lblClose");

            if (lblClose == null) return;

            lblClose.MouseLeftButtonDown += new MouseButtonEventHandler(lblClose_MouseLeftButtonDown);

            cboImportance = (ComboBox)base.GetTemplateChild("cboImportance");

            if (cboImportance == null) return;

            cboImportance.SelectionChanged += new SelectionChangedEventHandler(cboImportance_SelectionChanged);

            txtDesc = (TextBox)base.GetTemplateChild("txtDesc");

            if (txtDesc == null) return;

            dpStartDate = (SLControlLibrary.Resources.Controls.Calendar.DatePicker.ucDatePicker)base.GetTemplateChild("dpStartDate");

            if (dpStartDate == null) return;

            dpStartDate.DateSelectedEvent += new SLControlLibrary.Resources.Controls.Calendar.Events.DateSelectedHandler(dpStartDate_DateSelectedEvent);
            
            dpEndDate = (SLControlLibrary.Resources.Controls.Calendar.DatePicker.ucDatePicker)base.GetTemplateChild("dpEndDate");

            if (dpEndDate == null) return;

            dpEndDate.DateSelectedEvent += new SLControlLibrary.Resources.Controls.Calendar.Events.DateSelectedHandler(dpEndDate_DateSelectedEvent);

            txtStartTime = (TextBox)base.GetTemplateChild("txtStartTime");

            if (txtStartTime == null) return;

            txtEndTime = (TextBox)base.GetTemplateChild("txtEndTime");

            if (txtEndTime == null) return;

            HasLoaded = true;

            SetBindings();

            DisplayAppointment();
        }
        #endregion

        #region SetBindings
        private void SetBindings()
        {
            var vm = new OutlookVM { Appointment_StartDate = DateTime.Now, Appointment_EndDate = DateTime.Now };
            this.DataContext = vm;

            Binding b1 = new Binding() { Path = new PropertyPath("Appointment_StartDate"), Mode = BindingMode.TwoWay, Source = vm };
            this.SetBinding(ucEditAppointment.StartDateProperty, b1);

            dpStartDate.SetBinding(SLControlLibrary.Resources.Controls.Calendar.DatePicker.ucDatePicker.SelectedDateProperty, b1);

            Binding b2 = new Binding() { Path = new PropertyPath("Appointment_EndDate"), Mode = BindingMode.TwoWay, Source = vm };
            this.SetBinding(ucEditAppointment.EndDateProperty, b1);

            dpEndDate.SetBinding(SLControlLibrary.Resources.Controls.Calendar.DatePicker.ucDatePicker.SelectedDateProperty, b2);
        }
        #endregion

        #region DisplayAppointment
        public void DisplayAppointment()
        {
            if (HasLoaded)
            {
                if (CurrentAppointment != null)
                {
                    if (CurrentAppointment.StartDate.HasValue)
                        StartDate = CurrentAppointment.StartDate.Value;
                    else
                        StartDate = DateTime.Now;

                    if (CurrentAppointment.EndDate.HasValue)
                        EndDate = CurrentAppointment.EndDate.Value;
                    else
                        EndDate = DateTime.Now;

                    StartTime = CurrentAppointment.StartTime;
                    EndTime = CurrentAppointment.EndTime;
                    Desc = CurrentAppointment.Desc;

                    OptionsDataProvider Provider = new OptionsDataProvider();
                    cboImportance.ItemsSource = Provider.AppointmentValueList;
                    cboImportance.DisplayMemberPath = "Value";

                    if (CurrentAppointment.ID > 0)
                    {
                        int index = 0;
                        foreach (AppointmentValue _Value in Provider.AppointmentValueList)
                        {
                            if (_Value.ID == CurrentAppointment.Value.ID)
                                break;

                            index++;
                        }

                        cboImportance.SelectedIndex = index;
                    }
                }
            }
        }
        #endregion

        #region UpdateCurrentAppointment
        private void UpdateCurrentAppointment()
        {
            if (CurrentAppointment == null)
            {
                CurrentAppointment = new Appointment();
                CurrentAppointment.IsNewAppointment = true;

                OptionsDataProvider Provider = new OptionsDataProvider();
                cboImportance.ItemsSource = Provider.AppointmentValueList;
                cboImportance.DisplayMemberPath = "Value";
            }                
        }
        #endregion

        #region OnStartDate_Changed
        protected virtual void OnStartDate_Changed(DependencyPropertyChangedEventArgs e)
        {
            StartDate = (DateTime)e.NewValue;
            UpdateCurrentAppointment();
        }
        #endregion

        #region OnEndDate_Changed
        protected virtual void OnEndDate_Changed(DependencyPropertyChangedEventArgs e)
        {
            EndDate = (DateTime)e.NewValue;
            UpdateCurrentAppointment();
        }
        #endregion

        #region OnStartTime_Changed
        protected virtual void OnStartTime_Changed(DependencyPropertyChangedEventArgs e)
        {
            StartTime = (TimeSpan)e.NewValue;
            UpdateCurrentAppointment();
        }
        #endregion

        #region OnEndTime_Changed
        protected virtual void OnEndTime_Changed(DependencyPropertyChangedEventArgs e)
        {
            EndTime = (TimeSpan)e.NewValue;
            UpdateCurrentAppointment();
        }
        #endregion

        #region OnDesc_Changed
        protected virtual void OnDesc_Changed(DependencyPropertyChangedEventArgs e)
        {
            Desc = e.NewValue.ToString();
            UpdateCurrentAppointment();
        }
        #endregion

        #region OnIsNewAppointment_Changed
        protected virtual void OnIsNewAppointment_Changed(DependencyPropertyChangedEventArgs e)
        {
            IsNewAppointment = (Visibility)e.NewValue;
        }
        #endregion

        #region OnCurrentAppointment_Changed
        protected virtual void OnCurrentAppointment_Changed(DependencyPropertyChangedEventArgs e)
        {
            CurrentAppointment = (Appointment)e.NewValue;

            DisplayAppointment();
        }
        #endregion
        #endregion

        #region Events
        #region btnSubmit_Click
        private void btnSubmit_Click(object sender, RoutedEventArgs e)
        {
            Desc = txtDesc.Text;
            StartTime = TimeSpan.Parse(txtStartTime.Text);
            EndTime = TimeSpan.Parse(txtEndTime.Text);

            CurrentAppointment.StartDate = StartDate;
            CurrentAppointment.EndDate = EndDate;
            CurrentAppointment.StartTime = StartTime;
            CurrentAppointment.EndTime = EndTime;
            CurrentAppointment.Desc = Desc;
            CurrentAppointment.StartTime = StartTime;
            CurrentAppointment.EndTime = EndTime;

            if (Appointment_Submited != null)
                Appointment_Submited(CurrentAppointment, null);
        }
        #endregion

        #region btnClose_MouseLeftButtonUp
        private void btnClose_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (Appointment_Closed != null)
                Appointment_Closed(this, null);
        }
        #endregion

        #region lblClose_MouseLeftButtonDown
        private void lblClose_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (Appointment_Closed != null)
                Appointment_Closed(this, null);
        }
        #endregion

        #region cboImportance_SelectionChanged
        private void cboImportance_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            CurrentAppointment.Value = ((sender as ComboBox).SelectedItem as AppointmentValue);
        }
        #endregion

        #region dpStartDate_DateSelectedEvent
        private void dpStartDate_DateSelectedEvent(object sender, DateSelectedEventArgs e)
        {
            StartDate = (DateTime)sender;
        }
        #endregion

        #region dpEndDate_DateSelectedEvent
        private void dpEndDate_DateSelectedEvent(object sender, DateSelectedEventArgs e)
        {
            EndDate = (DateTime)sender;
        }
        #endregion
        #endregion
    }
}
